/*
 * @(#)ClassFrame.java        0.1 09/04/29
 * @version 	0.1 29 Apr 2009
 * @author 	Tran Xuan Thanh
 * 
 * The hien mot Class (hoac Enum, Interface), co chua cac Attribute va/hoac Method
 */


package GUI;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import Data.*;

/**
 * Cau truc ClassFrame
<ClassFrame>
	<classNamePanel>
		<classnameTextField />
	</classnamePanel>
	
	<splitPane>
		<attributesScrollPane>
			<fullAttributesPanel>
				<attributesPanel>
					<AttributeAndMethod>
						<nameTextField />
						<deleteButton />
					</AttributeAndMethod>
					....................
					<AttributeAndMethod>
						<nameTextField />
						<deleteButton />
					</AttributeAndMethod>
				</attributesPanel>
				<addAttributeButton />
			</fullAttributesPanel>
		</attributesScrollPane>
		
		<methodsScrollPane>
			<fullMethodsPanel>
				<methodsPanel>
					<AttributeAndMethod>
						<nameTextField />
						<deleteButton />
					</AttributeAndMethod>
					....................
					<AttributeAndMethod>
						<nameTextField />
						<deleteButton />
					</AttributeAndMethod>				
				</methodsPanel>
				<addMethodButton />
			</fullMethodsPanel>
		</methodsScrollPane>
	</splitPane>
	
</ClassFrame>
*/

public class ClassFrame extends JInternalFrame implements ActionListener {
	private final Color BACKGROUND = new Color(250, 250, 180);
	
	Log log;
	Classes classes;

	long id;
	int type;
	ClassFrame me = this;
	private MainFrame mainFrame;

	private JPanel classNamePanel;
	private TextField classNameTextField;
	private JPanel attributesPanel;
	private JButton addAttributeButton;
	private JButton deleteAllAttributeButton;
	private JPanel methodsPanel;
	private JButton addMethodButton;
	//private JButton deleteAllMethodButton;
	
	public ClassFrame(int _type, MainFrame m) {
		log = Log.getInstance();
		classes = Classes.getInstance();
		this.addMouseListener(new MouseHandler());
		type = _type;
		mainFrame = m;
		super.setResizable(true);
		ResourceBundle lang = Options.getLanguage();
		setLayout(new BorderLayout(2, 1));
		setBackground(BACKGROUND);
		setSize(150, 200);
		this.setBorder(BorderFactory.createLineBorder(Color.black));
		setVisible(true);
		
		// Panel chua ten cua class
		classNamePanel = new JPanel();
		classNamePanel.setLayout(new FlowLayout());
		classNamePanel.setBackground(BACKGROUND);
		classNamePanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK));
		add(classNamePanel, BorderLayout.NORTH);
		
		// The hien ten cua class
		classNameTextField = new TextField("", 11);
		classNameTextField.setBackground(BACKGROUND);
		classNameTextField.setBorder(null);
		classNamePanel.add(classNameTextField);
		
		// Panel chua cac attribute
		attributesPanel = new JPanel();
		attributesPanel.setBackground(BACKGROUND);
		JPanel fullAttributesPanel = new JPanel(new BorderLayout());
		fullAttributesPanel.add(attributesPanel);

		// Button them mot attribute
		addAttributeButton = new JButton(lang.getString("ClassFrame.addAttributeButton.text"));
		addAttributeButton.addActionListener(this);
		addAttributeButton.setBorder(null);
		addAttributeButton.setBackground(BACKGROUND);
		fullAttributesPanel.add(addAttributeButton, BorderLayout.SOUTH);
		JScrollPane attributesScrollPane= new JScrollPane(fullAttributesPanel, JScrollPane.VERTICAL_SCROLLBAR_NEVER, 
																	JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		
		attributesScrollPane.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK));
		deleteAllAttributeButton = new JButton(lang.getString("ClassFrame.deleteAllAttributeButton.text"));
		deleteAllAttributeButton.addActionListener(this);
		deleteAllAttributeButton.setBorder(null);
		deleteAllAttributeButton.setBackground(BACKGROUND);
		//fullAttributesPanel.add(deleteAllAttributeButton, BorderLayout.SOUTH);
		
	
		
		
		// Panel chua cac method
		methodsPanel = new JPanel();
		methodsPanel.setBackground(BACKGROUND);
		JPanel fullMethodsPanel = new JPanel(new BorderLayout());
		fullMethodsPanel.add(methodsPanel);

		// Button them mot method
		addMethodButton = new JButton(lang.getString("ClassFrame.addMethodButton.text"));
		addMethodButton.addActionListener(this);
		addMethodButton.setBorder(null);
		addMethodButton.setBackground(BACKGROUND);
		fullMethodsPanel.add(addMethodButton, BorderLayout.SOUTH);
		fullMethodsPanel.setBorder(BorderFactory.createLineBorder(Color.black));
		JScrollPane methodsScrollPane= new JScrollPane(fullMethodsPanel, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
																	JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		
		methodsScrollPane.setBorder(null);
		
		GridLayout t = new GridLayout(0, 1);
		
		t.setVgap(-7);
		methodsPanel.setLayout(t);
		attributesPanel.setLayout(t);
		
		
		
		//JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, attributesScrollPane, methodsScrollPane);
		//splitPane.setResizeWeight(0.5);
		
		JPanel splitPane = new JPanel(new GridLayout(0, 1));
		splitPane.add(attributesScrollPane);
		splitPane.add(methodsScrollPane);
		add(splitPane);
		
		
		

		attributesPanel.setBorder(null);
		fullAttributesPanel.setBorder(null);
		methodsPanel.setBorder(null);
		fullMethodsPanel.setBorder(null);
		//splitPane.setBorder(null);
		
		this.addInternalFrameListener(new InternalFrameHandler());
		
		switch(type) {
		case Data.Class.CLASS:
			break;
		case Data.Class.ABSTRACT_CLASS:
			Font font = new Font(classNameTextField.getFont().getName(),
					Font.ITALIC, classNameTextField.getFont().getSize());
			classNameTextField.setFont(font);
			font = new Font(addMethodButton.getFont().getName(), Font.BOLD + Font.ITALIC,
					addMethodButton.getFont().getSize());
			addMethodButton.setFont(font);
			font = new Font(addAttributeButton.getFont().getName(), Font.BOLD + Font.ITALIC,
					addAttributeButton.getFont().getSize());
			addAttributeButton.setFont(font);
			break;
		case Data.Class.ENUM:
			this.setTitle("<< Enum >>");
			break;
		case Data.Class.INTERFACE:
			this.setTitle("<< Interface >>");
			splitPane.remove(attributesScrollPane);
			break;
		}
	}

	public ClassFrame(Data.Class c, MainFrame m) {
		this(c.getType(), m);
		classNameTextField.setText(c.getName());
		LinkedList<String> attributes = c.getAttributes();
		LinkedList<String> methods = c.getMethods();
		
		int size = attributes.size();
		for (int i = 0; i < size; i++) {
			addAttribute(attributes.get(i));
		}
		
		size = methods.size();
		for (int i = 0; i < size; i++) {
			addMethod(methods.get(i));
		}
	}
	
	public ClassFrame(ClassFrame cf) {
		this(cf.getClassData(), cf.mainFrame);
		/*Data.Class classData = new Data.Class(cf.getClassData());
		Component tmp[] = cf.attributesPanel.getComponents();
		int size = tmp.length;
		for (int i = 0; i < size; i++) {
			attributesPanel.add(new Attribute((Attribute)tmp[i], this));
		}
		tmp = cf.methodsPanel.getComponents();
		size = tmp.length;
		for (int i = 0; i < size; i++) {
			methodsPanel.add(new Method((Method)tmp[i], this));
		}*/
	}
	
	/*public void copy(ClassFrame cf) {
		mainFrame = cf.mainFrame;
		attributesPanel.removeAll();
		methodsPanel.removeAll();
		
		Data.Class classData = new Data.Class(cf.getClassData());
		Component tmp[] = cf.attributesPanel.getComponents();
		int size = tmp.length;
		for (int i = 0; i < size; i++) {
			attributesPanel.add(new Attribute((Attribute)tmp[i], this));
		}
		tmp = cf.methodsPanel.getComponents();
		size = tmp.length;
		for (int i = 0; i < size; i++) {
			methodsPanel.add(new Method((Method)tmp[i], this));
		}
		this.updateUI();
	}*/
	
	public void actionPerformed(ActionEvent event) {
		if (event.getSource() == addAttributeButton) {
			addAttribute(null);
		} else if (event.getSource() == addMethodButton) {
			addMethod(null);
		}
	}
	
	/*
	 * Them mot attribute vao class
	 */
	public void addAttribute(String text) {
		AttributeMethod tmp = new Attribute(text, type, this);
		attributesPanel.add(tmp);
		this.updateUI();
		//log.push(new ClassWithShape(classData, this));
		addAttributeButton.scrollRectToVisible(attributesPanel.getVisibleRect());
		tmp.getNameReference().requestFocus();
		MainFrame.isSaved = false;
		MainFrame.isLogged = false;
	}
	
	/*
	 * Them mot method vao class
	 */
	public void addMethod(String text) {
		AttributeMethod tmp = new Method(text, type, this);
		methodsPanel.add(tmp);
		this.updateUI();
		//log.push(new ClassWithShape(classData, this));
		addMethodButton.scrollRectToVisible(methodsPanel.getVisibleRect());
		tmp.getNameReference().requestFocus();
		MainFrame.isSaved = false;
		MainFrame.isLogged = false;
	}
	
	/*
	 * Update mot class
	 */
	public void updateClass(Data.Class c) {
		attributesPanel.removeAll();
		methodsPanel.removeAll();
		classNameTextField.setText(c.getName());
		LinkedList<String> attributes = c.getAttributes();
		LinkedList<String> methods = c.getMethods();
		
		int size = attributes.size();
		for (int i = 0; i < size; i++) {
			addAttribute(attributes.get(i));
		}
		
		size = methods.size();
		for (int i = 0; i < size; i++) {
			addMethod(methods.get(i));
		}
	}
	
	public Data.Class getClassData() {
		return classes.getClass(id);
	}
	
	public void setId(long i) {
		id = i;
	}
	
	public long getId() {
		return id;
	}
	
	/*
	 * Luu thong tin tren ClassFrame vao mot Class
	 */
	public void save() {
		try {
			this.getClassData().removeAttributes();
			this.getClassData().removeMethods();
			this.getClassData().setName(classNameTextField.getText());
			Component tmp[] = this.attributesPanel.getComponents();
			int size = tmp.length;
			for (int i = 0; i < size; i++) {
				if (tmp[i] instanceof Attribute) {
					((Attribute)tmp[i]).save();
				}
			}
			
			tmp = this.methodsPanel.getComponents();
			size = tmp.length;
			for (int i = 0; i < size; i++) {
				if (tmp[i] instanceof Method) {
					((Method)tmp[i]).save();
				}
			}
			Lines lines = Lines.getInstance();
			log.push(classes.getClasses(), lines.getLines());
			MainFrame.isLogged = true;
		} catch (Exception e) {
			System.out.print("error");
		}
		
	}
	
	private class InternalFrameHandler extends InternalFrameAdapter {
		public void internalFrameActivated(InternalFrameEvent event) {
			me.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.RED));
		}
		public void internalFrameDeactivated(InternalFrameEvent event) {
			me.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.BLUE));
			if (mainFrame.lastActivedClassFrame != null) mainFrame.lastActivedClassFrame.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
			mainFrame.lastActivedClassFrame = me;
			save();
		}
	}
	
	private class MouseHandler extends MouseAdapter {
		public void mouseExited(MouseEvent e)  {
			//save();
		}
	}
}
